﻿using System;
using System.Web.UI;
using System.Text;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Drawing.Imaging;

using System.Collections;
using System.Reflection;

namespace ExIF35
{
    public partial class Form3 : Form
    {
        Roll thisRoll = new Roll();
        int counter = 0;
        
        public Form3(Roll rollOfExposures)
        {
            thisRoll = rollOfExposures;
            InitializeComponent();
        }


        private void Form3_Load(object sender, EventArgs e)
        {
            foreach (Exposure exp in thisRoll.exposures)
            {
                listView1.Items.Add(new ListViewItem(new String[]{exp.Number, exp.ImageFile}));
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            listView1.Items.Clear();
            foreach (Exposure exp in thisRoll.exposures)
            {
                listView1.Items.Add(new ListViewItem(new String[] { exp.Number, exp.ImageFile }));
            }
            counter = 0;
        }

        private void listView1_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
                doFileProcessing(files);
            }
        }
        private void doFileProcessing(String[] files)
        {
            foreach (String curFileName in files)
            {
                if (counter < thisRoll.exposures.Count)
                {
                    
                    if (!thisRoll.exposures[counter].ImageFile.Equals(""))
                    {
                        DialogResult result = MessageBox.Show("Replace file?", "Exposure " + thisRoll.exposures[counter].Number + " already contains a file, replace?", MessageBoxButtons.YesNo);
                        if (result == DialogResult.Yes)
                        {
                            thisRoll.exposures[counter].ImageFile = curFileName;
                            listView1.Items[counter] = new ListViewItem(new String[] { thisRoll.exposures[counter].Number, curFileName });
                        }
                    }
                    else
                    {
                        
                        thisRoll.exposures[counter].ImageFile = curFileName;
                        listView1.Items[counter] = new ListViewItem(new String[] { thisRoll.exposures[counter].Number, curFileName });
                    }
                    counter++;
                }
            }

          
        }

        private void listView1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Filename: " + thisRoll.exposures[0].ImageFile);
        }

        private void button1_Click(object sender, EventArgs e)
        {
           
            String file;
            int orientationbase = 0;
            for (int i = 0; i < counter; i++)
            {
                
                file = thisRoll.exposures[i].ImageFile;
                Exposure exp = thisRoll.exposures[i];
                FileInfo infoFile = new FileInfo(file);


                if (exp.DateDigitized.Equals(""))
                {
                    exp.DateDigitized = infoFile.CreationTime.ToString("yyyy:MM:dd HH:mm:ss");
                }

                switch (Convert.ToInt16(exp.Orientation))
                {
                    case 0: orientationbase = 1; break;
                    case 1: orientationbase = 6; break;
                    case 2: orientationbase = 8; break;
                    case 3: orientationbase = 3; break;
                }

                int lightsourcebase = 0;
                switch (Convert.ToInt16(exp.LightSource))
                {
                    case 0: lightsourcebase = 0; break;
                    case 1: lightsourcebase = 1; break;
                    case 2: lightsourcebase = 2; break;
                    case 3: lightsourcebase = 3; break;
                    case 4: lightsourcebase = 4; break;
                    case 5: lightsourcebase = 9; break;
                    case 6: lightsourcebase = 10; break;
                    case 7: lightsourcebase = 11; break;
                    case 8: lightsourcebase = 12; break;
                    case 9: lightsourcebase = 13; break;
                    case 10: lightsourcebase = 14; break; 
                    case 11: lightsourcebase = 15; break;
                    case 12: lightsourcebase = 17; break; 
                    case 13: lightsourcebase = 18; break;
                    case 14: lightsourcebase = 19; break;
                    case 15: lightsourcebase = 20; break;
                    case 16: lightsourcebase = 21; break; 
                    case 17: lightsourcebase = 22; break;
                    case 18: lightsourcebase = 23; break; 
                    case 19: lightsourcebase = 24; break; 
                    case 20: lightsourcebase = 255; break;
                
                }

                int fStop = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(exp.Aperture) * 10));
                if (!exp.Speed.Contains('/'))
                {
                    exp.Speed = exp.Speed + "/1";
                }


                Image Img = Image.FromFile(file);

                writeExIf(Img, 0x8827, 0x2, thisRoll.ISO); //ISO
                writeExIf(Img, 0x13B, 0x2, exp.Photographer); //Artist
                writeExIf(Img, 0x0132, 0x2, exp.Date); //Date Time
                writeExIf(Img, 0x9003, 0x2, exp.Date); //Date Time Original
                writeExIf(Img, 0x9004, 0x2, exp.DateDigitized); //Date Time Digitized
                
                writeExIf(Img, 0x0112, 0x3, orientationbase.ToString()); //Orientation
                writeExIf(Img, 0x8822, 0x3, exp.Program.ToString()); // Program
                writeExIf(Img, 0x9207, 0x3, exp.Meter.ToString()); //Metering Mode
                writeExIf(Img, 0x9209, 0x3, exp.Flash.ToString()); //Flash
                writeExIf(Img, 0x9208, 0x3, lightsourcebase.ToString()); // Light Source

                writeExIf(Img, 0x920A, 0x5, exp.FocalLength+"/1"); //Focal Length
                writeExIf(Img, 0xA405, 0x3, exp.FocalLength); //35mm Focal Length
                writeExIf(Img, 0x829D, 0x5, fStop.ToString()+"/10"); //F-Stop
                writeExIf(Img, 0x9202, 0x5, fStop.ToString() + "/10"); //Aperture
                //writeExIf(Img, 0x9201, 0x5, exp.Speed); //Shutter Speed
                writeExIf(Img, 0x829A, 0x5, exp.Speed); //Exposure Time
                
                writeExIf(Img, 0x320, 0x2, exp.Title); //Image Title
                writeExIf(Img, 0x10E, 0x2, exp.Description); //Image Description

                writeExIf(Img, 0x10F, 0x2, thisRoll.cameramake); //Equipment Make
                writeExIf(Img, 0x110, 0x2, thisRoll.cameramake+" "+thisRoll.cameramodel); //Equipment Model

                writeExIf(Img, 0x9000, 0x7, "48 50 50 49"); //ExIf version number
                writeExIf(Img, 0x0131, 0x2, "ExIf 35"); //Software Used

                if (chkPrint.Checked == true)
                {
                    String filmInfo = "Shot on "+thisRoll.FilmType;
                    writeExIf(Img, 0x9286, 0x2, filmInfo);
                }
                if (chkCopyright.Checked == true)
                {
                    writeExIf(Img, 0x8298, 0x2, "(C) "+DateTime.Now.ToString("yyyy") + " "+ exp.Photographer);
                }
                Img.Save("Exp_"+thisRoll.exposures[i].Number+".jpg");
                
                

            }
            MessageBox.Show("Finished Wrting ExIf");
        }

        public void writeExIf(Image tmpImg, int ID, short Type, String value)
        {
            char nullChar = '\0';

            PropertyItem tmpProp = tmpImg.GetPropertyItem(20624);
            tmpProp.Type = Type;
            tmpProp.Id = ID;
            //tmpProp.Len = value.Length;

            if (Type == 0x2) 
            { 
                tmpProp.Len = value.Length + 1; 
                value = value + nullChar;
                tmpProp.Value = ASCIIEncoding.ASCII.GetBytes(value);
            }
            else if (Type == 0x3)
            {
                Byte[] tmp1 = new Byte[2];
                tmp1[0] = Convert.ToByte(Convert.ToInt16(value));
                tmp1[1] = Convert.ToByte(0);
                //tmpProp.Value = BitConverter.GetBytes(Convert.ToInt16(value));
                tmpProp.Value = tmp1;
                tmpProp.Len = tmp1.Length;
            }
            else if (Type == 0x4)
            {
                tmpProp.Value = BitConverter.GetBytes(Convert.ToDouble(value));
            }
            else if (Type == 0x5)
            {
                
                Byte[] tmp1 =  BitConverter.GetBytes(Convert.ToInt32(value.Split('/')[0]));
                Byte[] tmp2 = BitConverter.GetBytes(Convert.ToInt32(value.Split('/')[1]));
                Byte[] tmp3 = new Byte[tmp1.Length + tmp2.Length];
                tmp1.CopyTo(tmp3,0);
                tmp2.CopyTo(tmp3, tmp1.Length);

                tmpProp.Value = tmp3;
                tmpProp.Len = tmp3.Length;
            }
            else if (Type == 0x7)
            {
                Byte[] tmp1 = new Byte[4];
                tmp1[0] = Convert.ToByte(Convert.ToInt16(value.Split(' ')[0]));
                tmp1[1] = Convert.ToByte(Convert.ToInt16(value.Split(' ')[1]));
                tmp1[2] = Convert.ToByte(Convert.ToInt16(value.Split(' ')[2]));
                tmp1[3] = Convert.ToByte(Convert.ToInt16(value.Split(' ')[3]));

                tmpProp.Value = tmp1;
                tmpProp.Len = tmp1.Length;
            }
            else if (Type == 0x10)
            {
                
            }
            else
            {
                tmpProp.Value = ASCIIEncoding.ASCII.GetBytes(value);
            }
            
            tmpImg.SetPropertyItem(tmpProp);
            value = "";
        }


    }
}
